home *** CD-ROM | disk | FTP | other *** search
- /*
- ** timed.c
- */
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/socket.h>
-
- #include <string.h>
- #include <stdlib.h>
- #include <sys/syslog.h>
- #include "timed_rev.h"
-
- static const char ver[] = VERSTAG;
-
- #pragma msg 105 ignore
-
- #define TEMPLATE "NAME/A,SOCKPTR/A/N,ID/A/N,ARGS/F"
-
- struct Args {
- char *name;
- long *sockptr;
- long *id;
- char *args;
- };
-
- struct global {
- struct ExecBase *e;
- struct DosLibrary *d;
- struct Library *s;
- int errno;
- };
-
- #define SysBase g->e
- #define DOSBase g->d
- #define SockBase g->s
-
- static void machtime_dg (struct global *g, int);
- static void daytime_dg (struct global *g, int);
- static void machtime_stream (struct global *g, int);
- static void daytime_stream (struct global *g, int);
- static void SPrintf (struct global *g, char *buf, char *ctl, ...);
- static int openlibs (struct global *g);
- static void closelibs (struct global *g);
- static int reply_inet (struct global *g, long id);
-
- struct inetmsg {
- struct Message msg;
- ULONG id;
- };
-
- long
- timed (void)
- {
- int s;
- long result = RETURN_FAIL;
- struct RDArgs *rdargs;
- struct global glob, *g = &glob;
- struct Args arg;
-
- SysBase = *((struct ExecBase **) 4L);
-
- if (openlibs (g))
- {
- memset ((char *) &arg, 0, sizeof (struct Args));
- if (rdargs = ReadArgs (TEMPLATE, (LONG *) &arg, NULL))
- {
- setup_sockets (5, &g->errno);
-
- /* now get our socket, if we can */
- if (*arg.sockptr && ((s = s_inherit ((void *) *arg.sockptr)) >= 0))
- {
- result = stricmp (arg.name, "time");
-
- if (arg.args && *arg.args == 'U')
- {
- /* UDP */
- if (result)
- daytime_dg (g, s); /* service name of daytime */
- else
- machtime_dg (g, s); /* service name of time */
- }
- else
- {
- /* TCP */
- if (result)
- daytime_stream (g, s); /* service name of daytime */
- else
- machtime_stream (g, s); /* service name of time */
- }
-
- result = RETURN_OK;
- s_close (s);
- }
-
- /* if id was nonzero, then we have to inform inetd that we are done */
- if (*arg.id)
- {
- result = reply_inet (g, *arg.id);
- }
-
- cleanup_sockets ();
-
- FreeArgs (rdargs);
- }
- closelibs (g);
- }
-
- return result;
- }
-
- static void
- daytime (struct global *g, char *str)
- {
- struct DateTime dt;
- char day [20], date [20], time [20];
-
- dt.dat_Format = FORMAT_DOS;
- dt.dat_Flags = 0;
- dt.dat_StrDay = day;
- dt.dat_StrTime = time;
- dt.dat_StrDate = date;
- DateStamp (&dt.dat_Stamp);
- DateToStr (&dt);
- SPrintf (g, str, "%s %s %s\r\n", day, date, time);
- }
-
-
- /* Return human-readable time of day */
- static void
- daytime_stream (struct global *g, int s)
- {
- char buffer [128];
-
- daytime (g, buffer);
- send (s, buffer, strlen (buffer), 0);
- }
-
- static void
- daytime_dg (struct global *g, int s)
- {
- char buffer [128];
- struct sockaddr sa;
- int size;
-
- size = sizeof (sa);
- if (recvfrom (s, buffer, sizeof (buffer), 0, &sa, &size) < 0)
- return;
- daytime (g, buffer);
- sendto (s, buffer, strlen (buffer), 0, &sa, sizeof (sa));
- }
-
-
- /*
- * Return a machine readable date and time, in the form of the
- * number of seconds since midnight, Jan 1, 1900. Since DateStamp
- * returns the number of seconds since midnight, Jan 1, 1978,
- * we must add 246144960 seconds.
- */
-
-
- static long
- machtime (struct global *g)
- {
- struct DateStamp ds;
- long t;
-
- DateStamp (&ds);
- t = (ds.ds_Days * 86400) + (ds.ds_Minute * 60) + ((long)(ds.ds_Tick / 50));
- t += 2461449600;
-
- return t;
- }
-
-
- static void
- machtime_stream (struct global *g, int s)
- {
- long result;
-
- result = machtime (g);
- send (s, (char *) &result, sizeof (result), 0);
- }
-
- static void
- machtime_dg (struct global *g, int s)
- {
- long result;
- struct sockaddr sa;
- int size;
-
- size = sizeof (sa);
- if (recvfrom (s, (char *) &result, sizeof (result), 0, &sa, &size) < 0)
- return;
-
- result = machtime (g);
- sendto (s, (char *) &result, sizeof (result), 0, &sa, sizeof (sa));
- }
-
- static void SPrintf (struct global *g, char *buf, char *ctl, ...)
- {
- RawDoFmt (ctl, (long *)(&ctl + 1), (void (*))"\x16\xC0\x4E\x75", buf);
- }
-
- static int
- openlibs (struct global *g)
- {
- if (g->d = (struct DosLibrary *) OpenLibrary ("dos.library", 0))
- {
- if (g->s = OpenLibrary ("inet:libs/socket.library", 0))
- {
- return 1;
- }
- CloseLibrary ((struct Library *) g->d);
- g->d = NULL;
- }
- return 0;
- }
-
- static void closelibs (struct global *g)
- {
- /* don't call me if these libraries didn't get opened! */
-
- CloseLibrary ((struct Library *) g->d);
- CloseLibrary (g->s);
-
- g->d = NULL;
- g->s = NULL;
-
- return;
- }
-
- static int
- reply_inet (struct global *g, long id)
- {
- int
- result = RETURN_OK;
- struct MsgPort
- *replyport,
- *msgport;
- struct inetmsg
- inet_message;
-
- if (replyport = CreateMsgPort ())
- {
- inet_message.id = id;
- inet_message.msg.mn_Node.ln_Type = NT_MESSAGE;
- inet_message.msg.mn_Length = sizeof (struct inetmsg);
- inet_message.msg.mn_ReplyPort = replyport;
-
- Forbid ();
- if (msgport = FindPort ("inetd"))
- {
- PutMsg (msgport, (struct Message *) &inet_message);
- Permit ();
- /* we can't exit until we received a reply */
- WaitPort (replyport);
- }
- else
- {
- Permit ();
- s_syslog (LOG_ERR, "TIMED: Couldn't find inetd port\n");
- result = RETURN_FAIL;
- }
- DeleteMsgPort (replyport);
- }
- else
- {
- s_syslog (LOG_ERR, "TIMED: Couldn't create reply port\n");
- result = RETURN_FAIL;
- }
-
- return result;
- }
-